package com.hello.sandbox.utils.compat;

import dalvik.system.DexFile;
import java.util.ArrayList;
import java.util.List;
import com.hello.sandbox.utils.Reflector;

/** Created by Milk on 2021/5/16. * ∧＿∧ (`･ω･∥ 丶　つ０ しーＪ 此处无Bug */
public class DexFileCompat {

  public static List<Long> getCookies(ClassLoader classLoader) {
    List<Long> cookies = new ArrayList<>();
    List<DexFile> dexFiles = getDexFiles(classLoader);
    for (DexFile dexFile : dexFiles) {
      cookies.addAll(getCookies(dexFile));
    }
    return cookies;
  }

  public static List<Long> getCookies(DexFile dexFile) {
    List<Long> cookies = new ArrayList<>();
    if (dexFile == null) return cookies;
    try {
      Object object = Reflector.with(dexFile).field("mCookie").get();
      if (BuildCompat.isM()) {
        for (long l : (long[]) object) {
          cookies.add(l);
        }
      } else {
        cookies.add((long) object);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
    return cookies;
  }

  private static List<DexFile> getDexFiles(ClassLoader classLoader) {
    List<DexFile> dexFiles = new ArrayList<>();
    Object[] dexElements = getDexElements(classLoader);
    for (Object dexElement : dexElements) {
      try {
        dexFiles.add(Reflector.with(dexElement).field("dexFile").<DexFile>get());
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
    return dexFiles;
  }

  private static Object[] getDexElements(ClassLoader classLoader) {
    Object dexPathList = getDexPathList(classLoader);
    if (dexPathList == null) {
      return new Object[] {};
    }
    try {
      return Reflector.with(dexPathList).field("dexElements").get();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return new Object[] {};
  }

  private static Object getDexPathList(ClassLoader classLoader) {
    try {
      return Reflector.on("dalvik.system.BaseDexClassLoader").field("pathList").get(classLoader);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }
}
